/*
 * Copyright 2009-2010 by The Regents of the University of California
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * you may obtain a copy of the License from
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package edu.ucr.cs.dblab.acestore.api;

import java.nio.ByteBuffer;

import edu.ucr.cs.dblab.acestore.base.datatypes.FloatSerDeserializer;
import edu.ucr.cs.dblab.acestore.base.datatypes.IntegerSerDeserializer;
import edu.ucr.cs.dblab.acestore.base.datatypes.ShortSerDeserializer;

/**
 * @author jarodwen
 * @created Jun 3, 2011
 */
public class PageAccessHelper {

    public static final int INTSIZE = IntegerSerDeserializer.getSingleton()
            .getTypeSize();

    public static final int FLOATSIZE = FloatSerDeserializer.getSingleton()
            .getTypeSize();

    public static final int SHORTSIZE = ShortSerDeserializer.getSingleton()
            .getTypeSize();

    public static final int RESERVED_END = INTSIZE * 1;

    public static int GetPageReference(ByteBuffer page) {
        return page.getInt(page.capacity() - INTSIZE - RESERVED_END);
    }

    public static void SetPageReference(ByteBuffer page, int pageRef) {
        page.putInt(page.capacity() - INTSIZE - RESERVED_END, pageRef);
    }

    public static int GetPageRecCount(ByteBuffer page) {
        return page.getInt(page.capacity() - 2 * INTSIZE - RESERVED_END);
    }

    public static int GetRecEndOffset(ByteBuffer page, int recIdx) {
        return page.getInt(page.capacity() - 2 * INTSIZE - RESERVED_END
                - (recIdx + 1) * INTSIZE);
    }

    public static void SetRecEndOffset(ByteBuffer page, int recIdx,
            int endOffset) {
        page.putInt(page.capacity() - 2 * INTSIZE - RESERVED_END - (recIdx + 1)
                * INTSIZE, endOffset);
    }

    public static int GetRecStartOffset(ByteBuffer page, int recIdx) {
        return recIdx == 0 ? 0 : GetRecEndOffset(page, recIdx - 1) + 1;
    }

    public static void SetPageRecCount(ByteBuffer page, int recCount) {
        page.putInt(page.capacity() - 2 * INTSIZE - RESERVED_END, recCount);
    }

    public static int GetRecFieldsCount(ByteBuffer page, int recIdx) {
        int startOffset = GetRecStartOffset(page, recIdx);
        return page.getInt(startOffset);
    }

    public static int GetRecField(ByteBuffer page, int recIdx, int fIdx)
            throws Exception {
        int startOffset = GetRecStartOffset(page, recIdx);
        int fieldsCount = page.getInt(startOffset);
        if (fIdx >= fieldsCount)
            throw new Exception("Try to load a field beyond the dimensionality");
        return page.getInt(startOffset + INTSIZE + INTSIZE * fieldsCount + fIdx
                * INTSIZE);
    }

    public static int GetRecValue(ByteBuffer page, int recIdx) throws Exception {
        int startOffset = GetRecStartOffset(page, recIdx);
        int fieldsCount = page.getInt(startOffset);
        return page.getInt(startOffset + INTSIZE + INTSIZE * fieldsCount
                + (fieldsCount - 1) * INTSIZE);
    }

    public static void SetRecValue(ByteBuffer page, int recIdx, int value) {
        int startOffset = GetRecStartOffset(page, recIdx);
        int fieldsCount = page.getInt(startOffset);
        page.putInt(startOffset + INTSIZE + INTSIZE * fieldsCount
                + (fieldsCount - 1) * INTSIZE, value);
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

}
